package com.kmxd.ams.app.convert.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.text.CharSequenceUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONObject;
import com.google.common.collect.Lists;
import com.kmxd.ams.app.convert.AbstractDocConvert;
import com.kmxd.ams.client.system.ISysConfigSvc;
import com.kmxd.ams.core.common.constant.ErrorCode;
import com.kmxd.ams.core.exception.BizException;
import com.kmxd.ams.core.exception.LogInfo;
import com.kmxd.ams.core.util.JSONUtils;
import com.yh.scofd.agent.HTTPAgent;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.io.File;
import java.io.FileOutputStream;
import java.util.Arrays;
import java.util.List;
import java.util.Map;

import static com.kmxd.ams.core.common.constant.ConfigConst.OSS_TRANSFER;

/**
 * pdf转换工具类
 *
 * @author nickbi
 */
@Service("youhong")
@Slf4j
@RequiredArgsConstructor
public class YouHongOfdService implements AbstractDocConvert {

  private final ISysConfigSvc sysConfigSvc;

  private List<String> offices =
      Arrays.asList(
          "doc", "docx", "xls", "xlsx", "ppt", "pptx", "wps", "wpt", "txt", "pdf", "eid", "eis",
          "eip", "rtf", "xps");
  private List<String> img = Arrays.asList("jpg", "jpeg", "png", "bmp", "gif", "tif", "tiff");
  private List<String> html = Arrays.asList("html");

  public static final String TYPE_UNSUPPORT = "不支持的格式";
  public static final String TYPE_OFFICES = "TYPE_OFFICES";
  public static final String TYPE_PDF = "TYPE_PDF";
  public static final String TYPE_IMG = "TYPE_IMG";
  public static final String TYPE_HTML = "TYPE_HTML";

  /**
   * 设置指定的转换对象
   *
   * @param strs
   * @param fileType
   */
  @Override
  public void setFileType(List<String> strs, String fileType) {
    switch (fileType) {
      case TYPE_OFFICES:
        offices = strs;
        break;
      case TYPE_IMG:
        img = strs;
        break;
      case TYPE_HTML:
        html = strs;
        break;
      default:
        break;
    }
  }

  /**
   * 获取 license
   *
   * @return
   */
  public boolean getLicense() {
    boolean flag = false;
    return flag;
  }
  /**
   * 根据文件名判断文件类型
   *
   * @param fileName
   * @return
   */
  private String getType(String fileName) {

    // 后缀
    String suffix = FileUtil.getSuffix(fileName);
    if (CharSequenceUtil.equals("pdf", suffix)) {
      return TYPE_PDF;
    }
    if (CollUtil.contains(offices, suffix)) {
      return TYPE_OFFICES;
    } else if (CollUtil.contains(img, suffix)) {
      return TYPE_IMG;
    } else if (CollUtil.contains(html, suffix)) {
      return TYPE_HTML;
    } else {
      return TYPE_UNSUPPORT;
    }
  }

  /**
   * 文件转化pdf
   *
   * @param srcPath 需要转换的文件地址
   * @param targetPath 转换后的pdf地址
   */
  @Override
  public void docConvert(String srcPath, String targetPath) throws Exception {

    String type = getType(srcPath);
    if (StrUtil.equalsIgnoreCase(type, TYPE_UNSUPPORT)) {
      throw new BizException(LogInfo.newInstance(), ErrorCode.EXCEPTION, "当前格式未找到转换实现！" + type);
    }
    if (!FileUtil.exist(srcPath)) {
      throw new BizException(LogInfo.newInstance(), ErrorCode.EXCEPTION, "原文件已经被删除！" + srcPath);
    }

    // 根据类型转换执行不同的转换
    switch (type) {
      case TYPE_OFFICES:
        officesToOfd(srcPath, targetPath);
        break;
      case TYPE_IMG:
        imageToDoubleLayerOfd(srcPath, targetPath);
        break;
      case TYPE_HTML:
        htmlFilesToOfd(srcPath, targetPath);
        break;
      case TYPE_PDF:
        pdfToOfd(srcPath, targetPath);
        break;
      default:
        break;
    }
  }

  /**
   * offices to ofd
   *
   * @param srcPath
   * @param targetPath
   * @throws Exception
   */
  private void officesToOfd(String srcPath, String targetPath) throws Exception {
    HTTPAgent ha = new HTTPAgent(getOfdUrl());
    File sourceFile = new File(srcPath);
    File ofdFile = new File(targetPath);
    FileOutputStream outputStream = new FileOutputStream(ofdFile);
    ha.officesToOFD(Lists.newArrayList(sourceFile), outputStream);
  }

  /**
   * offices to ofd
   *
   * @param srcPath
   * @param targetPath
   * @throws Exception
   */
  private void pdfToOfd(String srcPath, String targetPath) throws Exception {
    HTTPAgent ha = new HTTPAgent(getOfdUrl());
    File sourceFile = new File(srcPath);
    File ofdFile = new File(targetPath);
    FileOutputStream outputStream = new FileOutputStream(ofdFile);
    ha.pdfToOFD(FileUtil.readBytes(sourceFile), outputStream, null);
  }

  /**
   * office to pfd
   *
   * @param srcPath
   * @param targetPath
   * @throws Exception
   */
  private void officesToPdf(String srcPath, String targetPath) throws Exception {
    HTTPAgent ha = new HTTPAgent(getOfdUrl());
    File sourceFile = new File(srcPath);
    File ofdFile = new File(targetPath);
    FileOutputStream outputStream = new FileOutputStream(ofdFile);
    ha.officeToPDF(sourceFile, outputStream);
  }

  /**
   * office to pfd
   *
   * @param srcPath
   * @param targetPath
   * @throws Exception
   */
  private void officeToImage(String srcPath, String targetPath) throws Exception {
    HTTPAgent ha = new HTTPAgent(getOfdUrl());
    File sourceFile = new File(srcPath);
    File ofdFile = new File(targetPath);
    FileOutputStream outputStream = new FileOutputStream(ofdFile);
    ha.officeToImage(sourceFile, outputStream, 120, true);
  }

  /**
   * office to pfd
   *
   * @param srcPath
   * @throws Exception
   */
  private String getFileText(String srcPath) throws Exception {
    HTTPAgent ha = new HTTPAgent(getOfdUrl());
    File sourceFile = new File(srcPath);
    Map<Integer, String> fileText = ha.getFileText(sourceFile);
    return String.join("", fileText.values());
  }

  /**
   * image To Double Layer Ofd
   *
   * @param srcPath
   * @throws Exception
   */
  private void imageToDoubleLayerOfd(String srcPath, String targetPath) throws Exception {
    HTTPAgent ha = new HTTPAgent(getOfdUrl());
    File sourceFile = new File(srcPath);
    File ofdFile = new File(targetPath);
    FileOutputStream outputStream = new FileOutputStream(ofdFile);
    ha.setDoubleLayer(true);
    ha.setDoubleLayerDPI(120f);
    //    ha.imagesToDoubleLayerOFD(Lists.newArrayList(sourceFile), outputStream,null,"");
  }

  /**
   * image To Double Layer Ofd
   *
   * @param srcPath
   * @throws Exception
   */
  private void htmlFilesToOfd(String srcPath, String targetPath) throws Exception {
    HTTPAgent ha = new HTTPAgent(getOfdUrl());
    File sourceFile = new File(srcPath);
    File ofdFile = new File(targetPath);
    FileOutputStream outputStream = new FileOutputStream(ofdFile);
    ha.htmlFilesToOFD(Lists.newArrayList(sourceFile), outputStream);
  }

  /**
   * image To Double Layer Ofd
   *
   * @param url
   * @throws Exception
   */
  private void htmlToOfd(String url, String targetPath) throws Exception {
    HTTPAgent ha = new HTTPAgent(getOfdUrl());
    File ofdFile = new File(targetPath);
    FileOutputStream outputStream = new FileOutputStream(ofdFile);
    ha.htmlToOFD(url, outputStream);
  }

  @Override
  public int getFilePages(String srcPath) {
    try {
      HTTPAgent ha = new HTTPAgent(getOfdUrl());
      File sourceFile = new File(srcPath);
      return ha.getPageCount(sourceFile);
    } catch (Exception e) {
      return 0;
    }
  }

  public String getOfdUrl() {
    String configContentByKey = sysConfigSvc.getConfigContentByKey(OSS_TRANSFER);
    if (CharSequenceUtil.isBlank(configContentByKey)) {
      log.error("youhong ofd转换服务地址未配置，无法ocr");
      return ErrorCode.OCR_CONNECTION_REFUSED;
    }
    JSONObject obj = JSONUtils.parseObj(configContentByKey);
    String ocrURL = obj.getStr("transferURL");

    String serveUrl = getServeUrl(ocrURL);
    return serveUrl;
  }
}
